Estadística descriptiva


In [ ]:
import nltk
#nltk.download('book')

In [ ]:
text = '''Neither a recession nor a collapse in revenue has yet been enough to convince \
Russian President Vladimir Putin that it’s time to join with OPEC and cut oil output to \
boost prices. His reasons may be pragmatic rather than political. Russia’s Energy \
Minister Alexander Novak and his Saudi Arabian, Venezuelan and Qatari counterparts \
agreed to freeze output at January levels on Tuesday. The world’s second-largest crude \
producer faces numerous obstacles to any deal that would actually cut production, even if \
Putin decides it’s in the national interest. Reducing the flow of crude might damage \
Russia’s fields and pipelines, require expensive new storage tanks or simply take too long. \
Prior to Tuesday’s agreement, Novak had said he could consider reductions if other producers \
joined in. Yet Igor Sechin, chief executive officer of the country’s largest oil company \
Rosneft OJSC and a close Putin ally, has resisted, saying last week in London that \
coordination would be difficult because no major producer seems willing to pare output. \
"The history of relations with OPEC suggests that Russian companies are not keen to cut \
production," James Henderson, an oil and gas industry analyst at the Oxford Institute for \
Energy Studies, said by phone. "There are certain practical difficulties, and the companies \
would rather somebody else did that, and they could benefit once the price goes up."'''

Promedio de longitud de palabras (esta vez de verdad)

Trabajaremos de momento con una sola oración. Para esto separamos en oraciones:


In [ ]:
sentences = nltk.sent_tokenize(text)

In [ ]:
sentences

Y seleccionamos la primera oración:


In [ ]:
sentence = sentences[0]

In [ ]:
sentence

In [ ]:
words = nltk.word_tokenize(sentence)

In [ ]:
words

Recordamos la solución aproximada:


In [ ]:
len(sentence)/len(words)

Pero el promedio en realidad se calcula así:

$$\mu = {\sum_{w \in words}{|w|} \over {|words|}}$$

Es decir que sumamos la longitud de cada palabra, y dividimos por el número de palabras.

Calculamos la longitud de cada palabra:


In [ ]:
word_len = [len(w) for w in words]

print(word_len)

Paréntesis: también podemos ver cada palabra con su longitud:


In [ ]:
[(w,len(w)) for w in words]

Sumamos todas las longitudes:


In [ ]:
word_len_sum = sum(word_len)

word_len_sum

Y dividimos por el número de palabras:


In [ ]:
word_len_avg = word_len_sum/len(words)

word_len_avg

Distribuciones

La función FreqDist() nos da la distribución de frecuencia de los valores de una lista, p.ej.:


In [ ]:
nltk.FreqDist(['a','b','c','a','a','c','c','c'])

Podemos aplicar lo mismo a las longitudes de palabras:


In [ ]:
len_dist = nltk.FreqDist(word_len)

len_dist

FreqDist incorpora funcionalidad para visualizar la distribución:

Necesitamos incluir lo siguiente (en particular el %matplotlib inline) para que las gráficas aparezcan directamente dentro del Notebook.


In [ ]:
%matplotlib inline
import matplotlib.pyplot as plt

In [ ]:
len_dist.plot()

Para tenerlo no por orden de frecuencia, pero por orden de longitud de palabra, es un poco más complicado:

Tenemos que crear dos listas (de tamaño idéntico). La primera contiene solo las etiquetas (en nuestro caso la longitud de las palabras, pero también podrían ser las palabras mismas u otra cosa), y la segunda contiene los valores que corresponden a cada etiqueta.

Podemos usar matplotlib para crear gráficos:


In [ ]:
x=[length for length in len_dist.keys()]
y=[len_dist[length] for length in len_dist.keys()]

x,y

In [ ]:
plt.bar(x,y)

Métricas de dispersion

Las métricas de dispersión suelen basarse en la diferencia entre el valor promedio y el valor de cada ejemplo.

Por lo tanto calculamos para cada palabra la diferencia entre su longitud y la longitud esperada (promedio)


In [ ]:
word_len_diff = [len(w)-word_len_avg for w in words]

word_len_diff

Desviación estándar

Para tener una métrica de dispersión necesitamos agregar todas estas diferencias.

Como vemos, al hacer la resta obtenemos valores positivos o negativos, según si el valor del ejemplo es más grande o más pequeño del valor esperado. Primero nos tenemos que asegurar que cada diferencia cuente como valor positivo (de otra forma se cancelarían entre ellos). La forma más habitual de hacerlo es calculando el cuadrado de la diferencia


In [ ]:
word_len_sq_diff = [diff**2 for diff in word_len_diff]

word_len_sq_diff

Ahora agregamos todos estos valores calculando el promedio (suma de los valores dividida por el número de los mismos), lo que nos da la varianza:


In [ ]:
variance = sum(word_len_sq_diff)/len(word_len_sq_diff)

variance

Y finalmente la desviación estándar (que es la métrica más utilizada) es la raíz cuadrada de la varianza:


In [ ]:
import math
std_dev = math.sqrt(variance)

std_dev

También podemos hacer todos estos cálculos en un solo paso:


In [ ]:
math.sqrt(sum([(len(w)-word_len_avg)**2 for w in words])/len(words))

In [ ]: